package main;

import java.awt.*;
import java.awt.event.*;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class CohSuth extends Panel {
	Point P0 = new Point(0, 0), P1 = new Point(0, 0);
	public static int xMin = 100;
	public static int xMax = 800;
	public static int yMin = 100;
	public static int yMax = 400;
	private int firstX;
	private int firstY;
	private int lastX;
	private int lastY;
	private int points = 0;

	public static void main(String[] args) {
		CohSuth cS = new CohSuth();
		JFrame jF = new JFrame();
		jF.add("Center", cS);
		jF.pack();
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension screenSize = tk.getScreenSize();
		int screenHeight = screenSize.height;
		int screenWidth = screenSize.width;
		jF.setSize(900, 550);
		jF.setLocation(screenWidth / 5, screenHeight / 5);
		jF.setVisible(true);
	}

	public CohSuth() {
		setBackground(Color.WHITE);
		addMouseListener(new ControlMouseListener());
	}

	public void paint(Graphics g) {
		RenderingHints rH = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		rH.put(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		((Graphics2D) g).setRenderingHints(rH);
		g.setColor(new Color(100, 0, 255));
		g.drawRect(xMin, yMin, (xMax - xMin), (yMax - yMin));
		g.setColor(new Color(0, 255, 0));
		g.drawLine(P0.x, P0.y, P1.x, P1.y);
		g.setColor(new Color(255, 0, 0));
		if (clipper(P0, P1))
			g.drawLine(P0.x, P0.y, P1.x, P1.y);
	}

	private static int outCodes(Point P) {
		int Code = 0;

		if (P.y > yMax)
			Code |= 1; /* 0001 */
		else if (P.y < yMin)
			Code |= 2; /* 0010 */

		if (P.x > xMax)
			Code |= 4; /* 0100 */
		else if (P.x < xMin)
			Code |= 8; /* 1000 */

		return Code;
	}

	private static boolean rejectCheck(int outCode1, int outCode2) {
		if ((outCode1 & outCode2) != 0)
			return true;
		return (false);
	}

	private static boolean acceptCheck(int outCode1, int outCode2) {
		if ((outCode1 == 0) && (outCode2 == 0))
			return (true);
		return (false);
	}

	static boolean clipper(Point P0, Point P1) {
		int outCode0, outCode1;
		while (true) {
			outCode0 = outCodes(P0);
			outCode1 = outCodes(P1);
			if (rejectCheck(outCode0, outCode1))
				return (false);
			if (acceptCheck(outCode0, outCode1))
				return (true);
			if (outCode0 == 0) {
				int tempCoord;
				int tempCode;
				tempCoord = P0.x;
				P0.x = P1.x;
				P1.x = tempCoord;
				tempCoord = P0.y;
				P0.y = P1.y;
				P1.y = tempCoord;
				tempCode = outCode0;
				outCode0 = outCode1;
				outCode1 = tempCode;
			}
			if ((outCode0 & 1) != 0) {
				P0.x += (P1.x - P0.x) * (yMax - P0.y) / (P1.y - P0.y);
				P0.y = yMax;
			} else if ((outCode0 & 2) != 0) {
				P0.x += (P1.x - P0.x) * (yMin - P0.y) / (P1.y - P0.y);
				P0.y = yMin;
			} else if ((outCode0 & 4) != 0) {
				P0.y += (P1.y - P0.y) * (xMax - P0.x) / (P1.x - P0.x);
				P0.x = xMax;
			} else if ((outCode0 & 8) != 0) {
				P0.y += (P1.y - P0.y) * (xMin - P0.x) / (P1.x - P0.x);
				P0.x = xMin;
			}
		}
	}

	class ControlMouseListener implements MouseListener {

		@Override
		public void mouseClicked(MouseEvent e) {
			if (points == 0) {
				firstX = e.getX();
				firstY = e.getY();
				points++;
			} else if (points == 1) {
				lastX = e.getX();
				lastY = e.getY();
				points = 0;
				P0 = new Point(firstX, firstY);
				P1 = new Point(lastX, lastY);
				paint(getGraphics());
			}
		}

		@Override
		public void mouseEntered(MouseEvent e) {

		}

		@Override
		public void mouseExited(MouseEvent e) {

		}

		@Override
		public void mousePressed(MouseEvent e) {

		}

		@Override
		public void mouseReleased(MouseEvent e) {
		}
	}

	class Point {
		int x, y;

		Point(int xx, int yy) {
			this.x = xx;
			this.y = yy;
		}
	}
}